package com.onlineMIS.ORM.DAO.headQ.custMgmt;

import java.io.ByteArrayInputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;




import com.onlineMIS.ORM.DAO.Response;
import com.onlineMIS.ORM.DAO.headQ.SQLServer.ClientDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQEntityTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.finance.ChainAcctFlowDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.finance.ChainFinanceTraceImpl;
import com.onlineMIS.ORM.entity.base.Pager;
import com.onlineMIS.ORM.entity.chainS.user.ChainStore;
import com.onlineMIS.ORM.entity.headQ.SQLServer.ClientsMS;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadQTag;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadqEntityTag;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCust;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCustTemplate;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCustVO;
import com.onlineMIS.ORM.entity.headQ.finance.FinanceCategory;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplier;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplierTemplate;
import com.onlineMIS.ORM.entity.headQ.user.UserInfor;
import com.onlineMIS.action.headQ.custMgmt.HeadQCustMgmtFormBean;
import com.onlineMIS.common.Common_util;
import com.onlineMIS.common.ExcelUtil;
import com.onlineMIS.common.StrCheckUtils;
import com.onlineMIS.common.loggerLocal;
import com.onlineMIS.filter.SystemParm;

@Service
public class HeadQCustMgmtService {
	@Autowired
	private HeadQCustDaoImpl headQCustDaoImpl;
	@Autowired
	private ClientDAOImpl clientImpl;
	@Autowired
	private HeadQEntityTagDaoImpl headQEntityTagDaoImpl;
	@Autowired
	private HeadQTagDaoImpl headQTagDaoImpl;
	
	@Autowired
	private ChainAcctFlowDaoImpl chainAcctFlowDaoImpl;
	
	@Autowired
	private ChainFinanceTraceImpl chainFinanceTraceImpl;
	
	/**
	 * 获取当前页所有客户的信息
	 * @param uiBean
	 * @param basicData
	 */
	public Response getAllCust() {
		Response response = new Response();
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
//		DetachedCriteria custTotalCriteria = DetachedCriteria.forClass(HeadQCust.class);
//		//获取list的 criteria
//		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
	
		List<HeadQCust> custs = headQCustDaoImpl.getAll(true);
		

		response.setReturnValue(custs);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}
	
	/**
	 * 获取当前页所有客户的信息
	 * @param uiBean
	 * @param basicData
	 * @throws ParseException 
	 */
	public Response listCust(HeadQCust cust,Integer page, Integer rowPerPage, String sort, String sortOrder) throws ParseException {
		Response response = new Response();
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
		DetachedCriteria custTotalCriteria = DetachedCriteria.forClass(HeadQCust.class);
		//获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
		
		if (cust != null){
			String custName = StringUtils.trim(cust.getName());
			if(StrCheckUtils.isLetter(custName)) {
				custTotalCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}else {
				custTotalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}
			
			String pinyin = StringUtils.trim(cust.getPinyin());
			if (StringUtils.isNotEmpty(pinyin)){
				custCriteria.add(Restrictions.like("pinyin", pinyin, MatchMode.ANYWHERE));
			}
		}

		//1. 获取总条数
		custTotalCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(headQCustDaoImpl.getByCriteriaProjection(custTotalCriteria, true));
		
		//2. 获取当页数据
		if (sortOrder.equalsIgnoreCase("asc"))
		    custCriteria.addOrder(Order.asc(sort));
		else 
			custCriteria.addOrder(Order.desc(sort));
		custCriteria.addOrder(Order.asc("id"));
		List<HeadQCust> custs = headQCustDaoImpl.getByCritera(custCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		
		List<HeadQCustVO> custVOs = getCustVos(custs);
		
		
		dataMap.put("rows", custVOs);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}
	
	/**
	 * 搜索客户信息不分页
	 * @param cust
	 * @return
	 */
	public Response searchCust(HeadQCust cust){
		Response response = new Response();

		//获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
		
		if (cust != null){
			String pinyin = StringUtils.trim(cust.getPinyin());
			if (StringUtils.isNotEmpty(pinyin)){
				custCriteria.add(Restrictions.like("pinyin", pinyin, MatchMode.ANYWHERE));
			}
			
			String custName = StringUtils.trim(cust.getName());
			if (StringUtils.isNotEmpty(custName)){
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}
		}

		//2. 获取当页数据
		custCriteria.addOrder(Order.asc("status"));
		custCriteria.addOrder(Order.asc("pinyin"));
		List<HeadQCust> custs = headQCustDaoImpl.getByCritera(custCriteria, true);


		response.setReturnValue(custs);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}
	
	/**
	 * 更新或者创建的客户信息
	 * @param headQCust
	 * @return
	 */
	public Response createOrUpdateCust(HeadQCust headQCust,String tags,UserInfor loginUserInfor, int custId0){
		Response response = new Response();
		
		try {
			if (headQCust.getId() == 0){
				response.setFail("客户ID不能为空，请查找精算的客户ID");
				return response;				
			} else {
				//更新旧的客户信息
				HeadQCust headQCust2 = headQCustDaoImpl.get(headQCust.getId(), true);
				if (headQCust2 == null){
					headQCust.setPinyin(Common_util.getPinyinCode(headQCust.getName(), false));
					headQCust.setCreationDate(Common_util.getToday());
					headQCust.setLastUpdateBy(loginUserInfor.getUser_name());
					headQCust.setLastUpdateTime(Common_util.getToday());
					headQCustDaoImpl.save(headQCust, true);				
					headQEntityTagDaoImpl.saveEntityTag(headQCust.getId(), SystemParm.getQxCustTagId());
					response.setSuccess("成功创建新的客户");
				} else {
					if (custId0 != headQCust.getId()) {
						response.setFail("新增的客户信息已经存在于系统,无需新增");
						return response;
					}

					headQCust2.copyInforFromOther(headQCust);
					headQCust2.setPinyin(Common_util.getPinyinCode(headQCust2.getName(), false));
					headQCust2.setLastUpdateBy(loginUserInfor.getUser_name());
					headQCust2.setLastUpdateTime(Common_util.getToday());
					headQCustDaoImpl.saveOrUpdate(headQCust2, true);
					response.setSuccess("成功更新客户信息");
				}
			}
			
			/**不用精算后使用这段代码
            //创建新的
			if (headQCust.getId() == 0){
				headQCust.setPinyin(Common_util.getPinyinCode(headQCust.getName(), false));
				headQCust.setCreationDate(Common_util.getToday());
				headQCust.setLastUpdateBy(loginUserInfor.getUser_name());
				headQCust.setLastUpdateTime(Common_util.getToday());
				headQCustDaoImpl.save(headQCust, true);				
				headQEntityTagDaoImpl.saveEntityTag(headQCust.getId(), SystemParm.getQxCustTagId());
				response.setSuccess("成功创建新的客户");
				
			} else {
				//更新旧的客户信息
				HeadQCust headQCust2 = headQCustDaoImpl.get(headQCust.getId(), true);
				if (headQCust2 == null){
					response.setFail("查找原客户信息失败 : 查找Id " + headQCust.getId());
				} else {
					headQCust2.copyInforFromOther(headQCust);
					headQCust2.setPinyin(Common_util.getPinyinCode(headQCust2.getName(), false));
					headQCust2.setLastUpdateBy(loginUserInfor.getUser_name());
					headQCust2.setLastUpdateTime(Common_util.getToday());
					headQCustDaoImpl.saveOrUpdate(headQCust2, true);
					response.setSuccess("成功更新客户信息");
				}
			}
			**/
		} catch (Exception e){
			e.printStackTrace();
			response.setFail("更新客户信息失败 : " + e.getMessage());
		}
		
		return response;
	}
	
	/**
	 * 冻结客户信息
	 * @param custId
	 * @return
	 */
	public Response disableCust(int custId){
		Response response = new Response();
		String hql = "UPDATE HeadQCust SET status = ? WHERE id = ?";
		try {
		    Object[] values = {HeadQCust.CustStatusEnum.DELETED.getKey(), custId};
		
		    int record = headQCustDaoImpl.executeHQLUpdateDelete(hql, values, true);
		    if (record == 1)
		    	response.setSuccess("成功冻结客户数据");
		    else 
		    	response.setSuccess("冻结客户数据失败");
		} catch (Exception e){
			response.setFail("冻结客户信息失败 : " + e.getMessage());
		}
		
		return response;
	}
	
	/**
	 * 准备修改或者添加某个客户时
	 * @param cust
	 */
	public Response preEditCust(HeadQCust cust) {
		Response response = new Response();
		
		//当前是添加新客户
		if (cust == null || cust.getId() == 0){
			return response;
		} else {
			int id = cust.getId();
			HeadQCust cust2 = headQCustDaoImpl.get(id, true);
			if (cust2 != null){
				response.setReturnValue(cust2);
				return response;
			} else {
				response.setFail("无法获取客户信息 : " + id);
				return response;
			}	
		}
		
	}
	
	
	
	/**
	 * 总部用户获取这个用户可以看到的连锁店
	 * includeAllChain : 1 包含 所有连锁店 选项在第一页, 0不包含
	 * isAll : 1 是否列举所有的连锁店，0 或者只列举 父亲连锁店， -1 只列举儿子连锁店
	 * @param userInfor
	 * @return
	 */
	public Response getHeadCustListHQ(UserInfor userInfor, Pager pager, int isAll, int includeAllChain,String custName) {
		Response response = new Response();
		List<HeadQCust> headQCusts = new ArrayList<HeadQCust>(); 

		boolean cache = false;
		
		//1. check the pager
		if (pager.getTotalResult() == 0){
			DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);
			criteria.add(Restrictions.eq("status", ChainStore.STATUS_ACTIVE));
			//DetachedCriteria criteria = buildChainStoreHQCriteria(isAll);
			if (custName != null) {
				criteria.add(Restrictions.like("name",custName,MatchMode.ANYWHERE));
			}
			criteria.setProjection(Projections.rowCount());
			int totalRecord = Common_util.getProjectionSingleValue(headQCustDaoImpl.getByCriteriaProjection(criteria, false));
			pager.initialize(totalRecord);
		} else {
			pager.calFirstResult();
			cache = true;
		}
		
		//2. 获取连锁店列表
		DetachedCriteria searchCriteria = DetachedCriteria.forClass(HeadQCust.class);
		searchCriteria.add(Restrictions.eq("status", ChainStore.STATUS_ACTIVE));
		//searchCriteria.addOrder(Order.asc("pinyin"));
		if (custName !=null) {
			searchCriteria.add(Restrictions.like("name",custName,MatchMode.ANYWHERE));
		}
		headQCusts = headQCustDaoImpl.getByCritera(searchCriteria, pager.getFirstResult(), pager.getRecordPerPage(), cache);
		
		//3. 添加所有连锁店
		if (pager.getCurrentPage() == Pager.FIRST_PAGE && includeAllChain != 0){
			HeadQCust allHeadCust = headQCustDaoImpl.getAllHeadCustObject();
			headQCusts.add(0, allHeadCust);
		}
		
		response.setReturnValue(headQCusts);
		response.setReturnCode(Response.SUCCESS);
		
		return response;

	}

	
	/**
	 * 导出客户信息
	 * @param path
	 * @param formBean
	 * @return
	 */
	public Response generateHeadCustExcel(String path, HeadQCustMgmtFormBean formBean) {

		Response response = new Response();
		try {
			List<HeadQCust> allCusts = new ArrayList<HeadQCust>();
			Boolean isName = false;
			Boolean isTags = false;
			
			List<Integer> custIds = headQCustDaoImpl.selectIdsByName(formBean.getCustName(),formBean.getCustStatus());
			if (custIds.size() !=0) {
				isName = true;
			}
			
			List<Integer> custs = new ArrayList<Integer>();
			if (formBean.getTagGroups() != null && formBean.getTagGroups().length() !=0) {
				 custs = headQCustDaoImpl.getTagGroupsCusts(formBean.getTagGroups());
				isTags = true;
			}
			
			if (isName && isTags) {
				List<Integer> list = new ArrayList<Integer>(custs);
				list.retainAll(custIds);
				allCusts = headQCustDaoImpl.selectCustsByIds(list);
			}else if (isName) {
				allCusts = headQCustDaoImpl.selectCusts(formBean.getCustName());
			}else if ( isTags) {
				allCusts = headQCustDaoImpl.selectCustsByIds(custs);
			}else {
 				allCusts = headQCustDaoImpl.getAll(true);
			}
			
			List<HeadQCustVO> list = getCustVos(allCusts);

			HeadQCustTemplate template = new HeadQCustTemplate(path, list);
			HSSFWorkbook wb = template.process();
			ByteArrayInputStream byteArrayInputStream = ExcelUtil.convertExcelToInputStream(wb);

			response.setReturnValue(byteArrayInputStream);
			response.setReturnCode(Response.SUCCESS);
		} catch (Exception e) {
			loggerLocal.error(e);
			e.printStackTrace();
			response.setFail(e.getMessage());
		}
		return response;
	}

	
	/**
	 * 财务信息管理-分页查询客户信息
	 * @param formBean
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param sortOrder
	 * @return
	 * @throws ParseException 
	 */
	public Response listCustTag(HeadQCustMgmtFormBean formBean, Integer page, Integer rowPerPage, String sort,
			String sortOrder) throws ParseException {
		Response response = new Response();
		Map dataMap = new HashMap();
		List<HeadQCustVO> custVOs = new ArrayList<HeadQCustVO>();
		List<HeadQCustVO> footers = new ArrayList<HeadQCustVO>();
		HeadQCustVO footer = new HeadQCustVO();
		int total = 0;
		double sumBalance = 0;
		// 根据客户名称模糊查询客户 + 客户状态
		List<Integer> ids = headQCustDaoImpl.selectIdsByName(formBean.getCustName(),formBean.getCustStatus());		
		// 客户标签组

		if (formBean.getTagGroups() != null && formBean.getTagGroups().length() !=0) {
			List<Integer> custIds = headQCustDaoImpl.getTagGroupsCusts(formBean.getTagGroups());
			if (ids != null) {
				ids.retainAll(custIds);
			} else {
				ids = new ArrayList<Integer>();
				ids.addAll(custIds);
			}
		}

		// 获取总条数的 criteria
		DetachedCriteria custTotalCriteria = buildSearchCustCriteria(ids);
		custTotalCriteria.setProjection(Projections.rowCount());
		total = Common_util.getProjectionSingleValue(headQCustDaoImpl.getByCriteriaProjection(custTotalCriteria, true));

		// 获取合计sumBalance
		DetachedCriteria sumCriteria = buildSearchCustCriteria(ids);
		sumCriteria.setProjection(Projections.sum("currentAcctBalance"));
		Object sumObj = headQCustDaoImpl.getByCriteriaProjection(sumCriteria, true).get(0);
		if (sumObj != null)
			sumBalance = (Double) sumObj;
		
		// 获取list的 criteria
		DetachedCriteria custCriteria = buildSearchCustCriteria(ids);
		if (sort != null) {
			custCriteria.addOrder(Order.asc(sort));
		} else {
			custCriteria.addOrder(Order.desc("id"));
		}

		List<HeadQCust> custs2 = headQCustDaoImpl.getByCritera(custCriteria,
				Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		custVOs = getCustVos(custs2);

		footer.setName("合计");
		double currentFinance = 0;
		double prepaid = 0;
		footer.setCurrentAcctBalance(sumBalance);
		footers.add(footer);
		dataMap.put("footer", footers);
		dataMap.put("rows", custVOs);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	
	/**
	 * 根据客户id查询客户信息
	 * @param cust
	 * @param custIdSet
	 * @return
	 */
	private DetachedCriteria buildSearchCustCriteria(List<Integer> custIdSet) {
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);		
		if (custIdSet != null) {
			custIdSet.add(-1);
			custCriteria.add(Restrictions.in("id", custIdSet));
		}	
		return custCriteria;
	}

	
	/**
	 * 根据客户集合获取客户视图集合对象
	 * @param list
	 * @return
	 * @throws ParseException 
	 */
	public List<HeadQCustVO> getCustVos(List<HeadQCust> list) throws ParseException {

		List<HeadQCustVO> hVos = new ArrayList<HeadQCustVO>();
		if (list.size() > 0) {
			for (HeadQCust headQCust : list) {
				// 获取所有客户的tag_id
				List<Integer> tagIds = headQEntityTagDaoImpl.selectTagsByEntityId(headQCust.getId());
				List<HeadQTag> headQTags = headQTagDaoImpl.selectByIds(tagIds);
				String tags = "";
				if (headQTags != null) {
					for (int i = 0; i < headQTags.size(); i++) {
						if (i == headQTags.size() - 1) {
							tags += headQTags.get(i).getTagName();
						} else {
							tags += headQTags.get(i).getTagName() + ",";
						}
					}
				}
							
				//1. Get the current finance期初欠款
				double initialAcct = headQCust.getInitialAcctBalance();
				
			    //2.当前欠款
				double currentFinance = initialAcct + chainAcctFlowDaoImpl.getAcctFlowByCustId(headQCust.getId());
				currentFinance = Common_util.roundDouble(currentFinance, 2);
				
				//2. 客户预存金
				double currentPrepayAmount = headQCust.getPrepayInitialAmount() + chainFinanceTraceImpl.getSumOfFinanceCategory(FinanceCategory.PREPAY_ACCT_TYPE, headQCust.getId());
				currentPrepayAmount = Common_util.roundDouble(currentPrepayAmount, 2);

				HeadQCustVO hVo = new HeadQCustVO(headQCust.getId(), headQCust.getName(), headQCust.getPhone(),
						headQCust.getArea(), headQCust.getAddress(), headQCust.getInitialAcctBalance(), currentFinance,currentPrepayAmount,headQCust.getPrepayInitialAmount(),
						headQCust.getPrepayComment(),
						headQCust.getCurrentAcctBalance(), headQCust.getComment(), headQCust.getPinyin(),
						headQCust.getCreationDate(), tags, headQCust.getStatus());
				hVos.add(hVo);
			}

		}
		return hVos;
	}
	
}
